package cn.iocoder.yudao.module.project.controller.admin.kisbom;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
import cn.iocoder.yudao.module.project.controller.admin.order.vo.PreparationVO;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.io.IOException;
import java.util.stream.Collectors;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.yudao.module.project.config.projectDefine.HTTP_STATUS.ERROR_STATUS;

import cn.iocoder.yudao.module.project.controller.admin.kisbom.vo.*;
import cn.iocoder.yudao.module.project.dal.dataobject.kisbom.KisBomDO;
import cn.iocoder.yudao.module.project.service.kisbom.KisBomService;
import org.springframework.web.multipart.MultipartFile;

@Tag(name = "管理后台 - bom数据")
@RestController
@RequestMapping("/project/kis-bom")
@Validated
@Slf4j
public class KisBomController {

    @Resource
    private KisBomService kisBomService;

    @PostMapping("/create")
    @Operation(summary = "创建bom数据")
    // @PreAuthorize("@ss.hasPermission('project:kis-bom:create')")
    public CommonResult<String> createKisBom(@Valid @RequestBody KisBomSaveReqVO createReqVO) {
        return success(kisBomService.createKisBom(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新bom数据")
    // @PreAuthorize("@ss.hasPermission('project:kis-bom:update')")
    public CommonResult<Boolean> updateKisBom(@Valid @RequestBody KisBomSaveReqVO updateReqVO) {
        kisBomService.updateKisBom(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除bom数据")
    @Parameter(name = "id", description = "编号", required = true)
    // @PreAuthorize("@ss.hasPermission('project:kis-bom:delete')")
    public CommonResult<Boolean> deleteKisBom(@RequestParam("id") String id) {
        kisBomService.deleteKisBom(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得bom数据")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    // @PreAuthorize("@ss.hasPermission('project:kis-bom:query')")
    public CommonResult<KisBomRespVO> getKisBom(@RequestParam("id") String id) {
        KisBomDO kisBom = kisBomService.getKisBom(id);
        return success(BeanUtils.toBean(kisBom, KisBomRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得bom数据分页")
    // @PreAuthorize("@ss.hasPermission('project:kis-bom:query')")
    public CommonResult<PageResult<KisBomRespVO>> getKisBomPage(@Valid KisBomPageReqVO pageReqVO) {
        String specification = pageReqVO.getSpecification();
        if (StringUtils.isNotBlank(specification)) {
            specification = specification.replace("%20", " ");
            pageReqVO.setSpecification(specification);
        }
        PageResult<KisBomDO> pageResult = kisBomService.getKisBomPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, KisBomRespVO.class));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出bom数据 Excel")
    // @PreAuthorize("@ss.hasPermission('project:kis-bom:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportKisBomExcel(@Valid KisBomPageReqVO pageReqVO,
                                  HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<KisBomDO> list = kisBomService.getKisBomPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "bom数据.xls", "数据", KisBomRespVO.class,
                BeanUtils.toBean(list, KisBomRespVO.class));
    }




    @Operation(summary = "导出bom模板 Excel")
    @GetMapping(value = "/exportTemplate")
    public void exportTemplate(HttpServletResponse response){
        InputStream inputStream = null;
        String fileName = "bom导入模板.xlsx";
        try {
            ClassPathResource classPathResource = new ClassPathResource("/template/bom导入模板.xls");
            inputStream = classPathResource.getInputStream();
            Workbook excel = WorkbookFactory.create(inputStream);

            //使用输出流进行表格下载,基于浏览器作为客户端下载
            OutputStream out = response.getOutputStream();
            response.setContentType("application/vnd.ms-excel");//代表的是Excel文件类型
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));;//指定以附件形式进行下载
            excel.write(out);
            out.flush();
            out.close();
            excel.close();
        } catch (Exception e) {
        } finally {
            IoUtil.close(inputStream);
        }
    }

    @PostMapping("/importBom")
    @Operation(summary = "导入bom Excel")
    public CommonResult<Boolean> importBom(@RequestParam("file") MultipartFile file) {
        try {
            long start = System.currentTimeMillis();
            ExcelReader excelReader = ExcelUtil.getReader(file.getInputStream());
            // Sheet sheet = excelReader.getSheet();


            List<Sheet> sheets = excelReader.getSheets();
            Workbook workbook = sheets.get(0).getWorkbook();
            for (int sheetNum = 0; sheetNum < sheets.size(); sheetNum++) {
                boolean sheetHidden = workbook.isSheetHidden(sheetNum);

                if (sheetHidden) {
                    continue;
                }


                String sheetName = sheets.get(sheetNum).getSheetName();
                excelReader = ExcelUtil.getReader(file.getInputStream(), sheetName);
                List<List<Object>> list = excelReader.read();

                if (CollectionUtil.isNotEmpty(list)) {
                    if (list.size() > 2) {
                        List<KisBomDO> importDataList = new ArrayList<>();

                        // bom型号
                        Object type = list.get(2).get(1);

                        // bom导入日期
                        List<Object> thirdLine = list.get(2);
                        Object receiptDate = list.get(2).get(4);
                        for (Object obj : thirdLine) {
                            String s = obj.toString();
                            if (StringUtils.isNotBlank(s) && s.contains("日期")) {
                                receiptDate = s;
                            }
                        }

                        String dateStr = "";
                        // 从第七行开始读取,一直读到倒数第二行
                        for (int i = 6; i < list.size() - 1; i++) {
                            KisBomDO kisBomDO = new KisBomDO();

                            if (type != null && !type.equals("")) {
                                // 型号只取前6位
                                String type0 = type.toString().replace("型号：", "");
                                kisBomDO.setType(type0.substring(0, 6));
                            }

                            if (receiptDate != null && !receiptDate.equals("")) {
                                String orderDateStr = receiptDate.toString()
                                        .replace("日期:", "")
                                        .replace("日期：", "")
                                        .replace("/", "-")
                                        .replace(".", "-")
                                        .replaceAll("\\s*", "");
                                // LocalDateTime orderDateTime = LocalDateTimeUtil.parse(orderDateStr);

                                String[] dateArr = orderDateStr.split("-");
                                if (dateArr.length == 3) {
                                    String year = dateArr[0];
                                    String month = dateArr[1];
                                    String day = dateArr[2];

                                    if (month.length() == 1) {
                                        month = "0" + month;
                                    }
                                    if (day.length() == 1) {
                                        day = "0" + day;
                                    }
                                    dateStr = year + "-" + month + "-" + day;
                                    LocalDate localDate = LocalDate.parse(dateStr);
                                    LocalDateTime receiptDateTime = localDate.atTime(0, 0, 0);
                                    kisBomDO.setReceiptDate(receiptDateTime);
                                }
                            }

                            // 织板编码
                            Object code = list.get(i).get(0);
                            if (code != null && !code.equals("")) {
                                kisBomDO.setCode(code.toString());
                                kisBomDO.setId(code.toString() + "_" + kisBomDO.getType());
                            }

                            // 织板规格
                            Object specification = list.get(i).get(1);
                            if (specification != null && !specification.equals("")) {
                                kisBomDO.setSpecification(specification.toString());
                            }

                            if (StringUtils.isNotBlank(kisBomDO.getCode())
                                    && StringUtils.isNotBlank(kisBomDO.getSpecification())
                            ) {
                                importDataList.add(kisBomDO);
                            }

                        }

                        if (CollectionUtil.isNotEmpty(importDataList)) {
                            List<String> ids = importDataList.stream()
                                    .map(c -> {
                                        return c.getId();
                                    })
                                    .distinct()
                                    .collect(Collectors.toList());
                            Map<String, Object> params = new HashMap<>();
                            params.put("ids", ids);

                            // 查询已经存在的bom数据,这些将不再写入库中
                            List<KisBomDO> savedList = kisBomService.selectSavedList(params);
                            List<KisBomDO> updateList = new ArrayList<KisBomDO>();
                            List<KisBomDO> insertList = new ArrayList<KisBomDO>();

                            for (KisBomDO record : importDataList) {
                                boolean issaved = false;

                                if (null != savedList && savedList.size() > 0) {
                                    for (KisBomDO saved : savedList) {
                                        if (
                                                saved.getId().equals(record.getId())
                                        ) {
                                            record.setDeleted(false);
                                            record.setId(saved.getId());
                                            updateList.add(record);
                                            issaved = true;
                                            break;
                                        }
                                    }

                                }

                                if (!issaved) {
                                    record.setDeleted(false);
                                    insertList.add(record);
                                }
                            }

                            kisBomService.insertRecord(insertList);
                            kisBomService.updateRecord(updateList);

                        }
                    }

                }
            }
            for (Sheet sheet : sheets) {
            }

            System.out.println("取excel完毕：" +(System.currentTimeMillis() - start)+"}毫秒");
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new ServiceException(ERROR_STATUS, "导入bom失败");
        }
        return success(true);
    }

    @GetMapping("/typeList")
    @Operation(summary = "获取型号列表")
    // @PreAuthorize("@ss.hasPermission('project:kis-bom:query')")
    public CommonResult<List<String>> selectTypeList(String type) {
        List<String> result = kisBomService.selectTypeList(type);
        return success(result);
    }

    @GetMapping("/codeList")
    @Operation(summary = "根据型号获取物料编号列表")
    // @PreAuthorize("@ss.hasPermission('project:kis-bom:query')")
    public CommonResult<List<PreparationVO>> selectCodeListByType(@RequestParam("type") String type) {
        List<PreparationVO> result = kisBomService.selectCodeListByType(type);
        return success(result);
    }

    @RequestMapping("/bomPage")
    @Operation(summary = "获得bom主数据分页")
    public CommonResult<PageResult<KisBomRespVO>> getBomPage(@Valid @RequestBody KisBomPageReqVO pageReqVO) {
        Map<String, Object> params = new HashMap<>();
        params.put("pageNo", (pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize());
        params.put("pageSize", pageReqVO.getPageSize());

        String type = pageReqVO.getType();
        if (StringUtils.isNotBlank(type)) {
            params.put("type", type);
        }

        String[] dateReq = pageReqVO.getDateReq();
        if (null != dateReq && dateReq.length == 2) {
            String startTime = dateReq[0];
            String endTime = dateReq[1];
            if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
                LocalDate startDate = LocalDate.parse(startTime);
                LocalDate endDate = LocalDate.parse(endTime);
                params.put("startDate", startDate);
                params.put("endDate", endDate);
            }
        }

        List<KisBomRespVO> kisBomRespVOS = kisBomService.selectBomList(params);
        Long count = kisBomService.countBomList(params);

        PageResult<KisBomRespVO> result = new PageResult<>();
        result.setList(kisBomRespVOS);
        result.setTotal(count);

        return success(result);
    }

}